/**
 * Vue项目导出服务
 * 将画布内容导出为完整的Vue项目，保留所有组件交互功能
 */

import { ElMessage } from 'element-plus';
import { saveAs } from 'file-saver';
import JSZip from 'jszip';
import { cloneDeep } from 'lodash-es';
import autoComponentLoader from './AutoComponentLoader';
import { kebabCase, camelCase, upperFirst } from 'lodash-es';

class VueProjectExportService {
  constructor() {
    this.initialized = false;
    this.componentsMap = new Map();
    this.componentDependencies = new Set();
    this.componentTypeToPathMap = {}; // 初始化为空对象，将在initialize方法中动态填充
    this.usedComponentTypes = [];
  }

  /**
   * 初始化导出服务
   */
  async initialize() {
    if (this.initialized) return;

    try {
      // 初始化组件加载器
      await autoComponentLoader.initialize();

      // 扫描并构建组件映射表
      await this.buildComponentsMap();

      this.initialized = true;
    } catch (error) {
      console.error('[VueProjectExportService] 初始化失败:', error);
      ElMessage.error('Vue项目导出服务初始化失败');
    }
  }

  /**
   * 扫描组件库并构建组件类型到路径的映射
   */
  async buildComponentsMap() {
    try {
      console.log('[DEBUG] 开始扫描组件库并构建组件映射');
      
      // 要扫描的所有组件目录
      const componentDirs = ['basic', 'business', 'custom'];
      this.componentTypeToPathMap = {}; // 重置映射
      console.log('[DEBUG] 已重置componentTypeToPathMap');

      // 方式3: 使用AutoComponentLoader已加载的组件信息（最优方案）
      if (autoComponentLoader && autoComponentLoader.initialized) {
        console.log('[DEBUG] 尝试使用AutoComponentLoader已加载的组件信息');
        
        // 直接使用AutoComponentLoader的路径映射
        const { componentPaths } = autoComponentLoader;
        
        // 转换到我们需要的格式
        for (const [componentType, path] of Object.entries(componentPaths)) {
          this.componentTypeToPathMap[componentType] = path;
          console.log(`[DEBUG] 从AutoComponentLoader添加组件映射: ${componentType} -> ${path}`);
        }
        
        console.log('[DEBUG] 使用AutoComponentLoader扫描完成，组件数量:', Object.keys(this.componentTypeToPathMap).length);
        console.log('[DEBUG] 组件映射表:', this.componentTypeToPathMap);
        console.log('[VueProjectExportService] 已从AutoComponentLoader获取组件库:', Object.keys(this.componentTypeToPathMap).length, '个组件');
        return;
      }

      // 方式1: 使用import.meta.glob (仅在Vite环境下有效)
      if (typeof import.meta !== 'undefined' && import.meta.glob) {
        console.log('[DEBUG] 尝试使用import.meta.glob扫描组件');
        
        // 静态导入所有目录的组件，因为import.meta.glob不支持动态路径
        const basicComponents = import.meta.glob('/src/components/library/basic/*/index.vue');
        const businessComponents = import.meta.glob('/src/components/library/business/*/index.vue');
        const customComponents = import.meta.glob('/src/components/library/custom/*/index.vue');
        
        console.log('[DEBUG] 扫描结果: basic:', Object.keys(basicComponents).length, 
                   'business:', Object.keys(businessComponents).length, 
                   'custom:', Object.keys(customComponents).length);

        // 合并所有组件
        const allComponents = {
          ...basicComponents,
          ...businessComponents,
          ...customComponents
        };

        // 处理所有找到的组件
        for (const path in allComponents) {
          // 提取组件类型，例如从 '/src/components/library/basic/button/index.vue' 提取 'button'和'basic'
          const match = path.match(/\/components\/library\/([^/]+)\/([^/]+)\/index\.vue$/);
          if (match && match[1] && match[2]) {
            const componentDir = match[1]; // basic, business, custom
            const componentName = match[2]; // button, input, etc.
            const componentType = `ew-${componentName}`;
            const relativePath = `${componentDir}/${componentName}`;
            this.componentTypeToPathMap[componentType] = relativePath;
            console.log(`[DEBUG] 添加组件映射: ${componentType} -> ${relativePath}`);
          } else {
            console.log(`[DEBUG] 路径不匹配正则表达式: ${path}`);
          }
        }

        console.log('[DEBUG] 使用import.meta.glob扫描完成，组件数量:', Object.keys(this.componentTypeToPathMap).length);
        console.log('[DEBUG] 组件映射表:', this.componentTypeToPathMap);
        console.log('[VueProjectExportService] 已自动扫描组件库:', Object.keys(this.componentTypeToPathMap).length, '个组件');
        return;
      }

      // 方式2: 如果在Electron环境中，可以使用Node.js的fs模块
      if (typeof window !== 'undefined' && window.electron) {
        console.log('[DEBUG] 尝试使用Electron的fs模块扫描组件');
        
        try {
          // 检查window.electron.fs是否正确初始化
          if (!window.electron.fs || typeof window.electron.fs.readdir !== 'function') {
            console.error('[DEBUG] window.electron.fs不存在或者readdir方法不可用');
            throw new Error('fs.readdir方法不可用');
          }
          
          const fs = window.electron.fs;
          const componentsDir = 'src/components/library';
          console.log(`[DEBUG] 组件库目录: ${componentsDir}`);

          // 扫描所有组件目录
          for (const dir of componentDirs) {
            try {
              console.log(`[DEBUG] 扫描目录: ${componentsDir}/${dir}`);
              const componentSubDirs = await fs.readdir(`${componentsDir}/${dir}`);
              console.log(`[DEBUG] 在目录 ${dir} 中找到子目录:`, componentSubDirs);

              for (const subDir of componentSubDirs) {
                const componentType = `ew-${subDir}`;
                const relativePath = `${dir}/${subDir}`;
                console.log(`[DEBUG] 处理子目录: ${subDir}, 组件类型: ${componentType}, 相对路径: ${relativePath}`);

                // 检查是否存在index.vue文件
                const indexPath = `${componentsDir}/${relativePath}/index.vue`;
                try {
                  console.log(`[DEBUG] 检查文件是否存在: ${indexPath}`);
                  await fs.access(indexPath);
                  this.componentTypeToPathMap[componentType] = relativePath;
                  console.log(`[DEBUG] 添加组件映射: ${componentType} -> ${relativePath}`);
                } catch (e) {
                  // 文件不存在，跳过
                  console.warn(`[DEBUG] 组件 ${relativePath} 没有index.vue文件: ${e.message}`);
                  console.warn(`[VueProjectExportService] 组件 ${relativePath} 没有index.vue文件`);
                }
              }
            } catch (e) {
              console.warn(`[DEBUG] 读取目录 ${dir} 失败: ${e.message}`);
              console.warn(`[VueProjectExportService] 读取目录 ${dir} 失败:`, e);
            }
          }

          console.log('[DEBUG] 使用Electron/fs扫描完成，组件数量:', Object.keys(this.componentTypeToPathMap).length);
          console.log('[DEBUG] 组件映射表:', this.componentTypeToPathMap);
          console.log('[VueProjectExportService] 已自动扫描组件库:', Object.keys(this.componentTypeToPathMap).length, '个组件');
          return;
        } catch (e) {
          console.error('[DEBUG] 使用Node.js扫描组件失败:', e.message);
          console.error('[VueProjectExportService] 使用Node.js扫描组件失败:', e);
          throw e; // 向上抛出错误，而不使用降级方案
        }
      }

      // 如果无法扫描，输出错误并抛出异常
      const error = new Error('无法自动扫描组件库，请检查Electron环境配置');
      console.error('[DEBUG] 无法自动扫描组件库，环境不支持');
      console.error('[VueProjectExportService] 无法自动扫描组件库');
      throw error;

    } catch (error) {
      console.error('[DEBUG] 构建组件映射失败:', error);
      console.error('[VueProjectExportService] 构建组件映射失败:', error);
      this.componentTypeToPathMap = {}; // 确保是一个空对象而不是undefined
      throw error; // 向上抛出错误，让调用方处理
    }
  }

  /**
   * 确保所有使用的组件都有映射
   * @param {Set<string>} usedComponentTypes 使用的组件类型集合
   */
  async ensureComponentsMapping(usedComponentTypes) {
    // 检查是否所有使用的组件都有映射
    const missingComponents = [];
    for (const type of usedComponentTypes) {
      if (!this.componentTypeToPathMap[type]) {
        missingComponents.push(type);
      }
    }

    // 如果有缺失的组件映射，尝试重新扫描
    if (missingComponents.length > 0) {
      console.warn(`[VueProjectExportService] 发现未映射的组件类型: ${missingComponents.join(', ')}`);
      await this.buildComponentsMap();

      // 再次检查
      const stillMissing = [];
      for (const type of missingComponents) {
        if (!this.componentTypeToPathMap[type]) {
          stillMissing.push(type);
        }
      }

      // 输出警告，但不中断导出流程
      if (stillMissing.length > 0) {
        console.warn(`[VueProjectExportService] 仍有未映射的组件类型: ${stillMissing.join(', ')}`);
      }
    }
  }

  /**
   * 导出为Vue项目
   * @param {Array} components 画布组件数组
   * @param {Object} options 导出选项
   * @returns {Promise<Blob>} 打包后的项目ZIP文件
   */
  async exportVueProject(canvasData, options = {}) {
    try {
      const projectName = options.projectName || 'easy-window-export';
      const includeElectron = options.includeElectron || false;
      const includeBackend = options.includeBackend || false;
      const outputPath = options.outputPath || '';
      const saveFile = options.saveFile !== false; // 默认为true

      console.log(`[DEBUG] 开始导出Vue项目: ${projectName}`, options);
      console.log(`[DEBUG] Canvas数据:`, canvasData);
      console.log(`[VueProjectExportService] 开始导出Vue项目: ${projectName}`);

      // 验证画布数据
      if (!canvasData || !canvasData.components || !Array.isArray(canvasData.components)) {
        console.error('[DEBUG] 无效的画布数据:', canvasData);
        throw new Error('无效的画布数据，无法导出项目');
      }

      // 更新状态
      this.isExporting = true;
      this.progress = 0;
      this.exportMessage = '正在准备导出...';

      // 创建ZIP文件
      const zip = new JSZip();

      // 构建组件映射表
      try {
        await this.buildComponentsMap();
        console.log(`[DEBUG] 组件映射表构建完成，包含 ${Object.keys(this.componentTypeToPathMap).length} 个组件`);
      } catch (error) {
        console.error('[DEBUG] 组件映射表构建失败:', error);
        ElMessage.error('组件库扫描失败: ' + error.message);
        throw error;
      }
      
      this.updateProgress(10, '生成项目结构');

      // 收集使用的组件类型
      console.log(`[DEBUG] 开始收集使用的组件，组件数量:`, canvasData.components.length);
      this.collectUsedComponentTypes(canvasData.components);
      
      if (this.usedComponentTypes.length === 0) {
        console.warn('[DEBUG] 画布上没有使用任何自定义组件');
        ElMessage.warning('画布上没有使用任何自定义组件');
      } else {
        console.log(`[DEBUG] 收集组件完成，使用的组件类型:`, this.usedComponentTypes);
      }

      // 生成项目结构
      this.generateProjectStructure(zip, projectName);
      this.updateProgress(20, '复制静态资源');

      // 复制静态资源
      await this.copyStaticAssets(zip, projectName);
      this.updateProgress(30, '生成配置文件');

      // 生成配置文件 - 传递includeBackend参数
      this.generateConfigFiles(zip, projectName, includeElectron, includeBackend);
      this.updateProgress(40, '生成页面文件');

      // 生成主页面文件
      zip.file(`${projectName}/src/views/MainPage.vue`, this.generateMainPageVue(projectName, canvasData));
      this.updateProgress(50, '复制组件到导出项目');

      // 复制组件到导出项目 - 只复制画布上使用到的组件
      if (this.usedComponentTypes.length > 0) {
        console.log(`[DEBUG] 准备复制组件到导出项目，组件数量:`, this.usedComponentTypes.length);
        try {
          await this.copyComponentsToExport(zip, projectName, this.usedComponentTypes);
        } catch (error) {
          console.error('[DEBUG] 复制组件失败:', error);
          ElMessage.error('复制组件失败: ' + error.message);
          // 尝试继续导出过程，但会影响导出项目的完整性
        }
      } else {
        console.warn('[DEBUG] 没有需要复制的组件');
      }
      
      this.updateProgress(60, '导出打包...');

      // 创建ZIP文件
      const content = await zip.generateAsync({
        type: 'blob',
        compression: 'DEFLATE',
        compressionOptions: {
          level: 9
        }
      }, (metadata) => {
        this.updateProgress(60 + Math.floor(metadata.percent * 0.4), '导出打包中...');
      });

      // 下载或保存ZIP文件
      if (outputPath && window.electron && window.electron.fs) {
        // 使用Electron保存文件
        const pathToSave = outputPath + (outputPath.endsWith('/') ? '' : '/') + `${projectName}.zip`;
        await window.electron.fs.writeFile(pathToSave, await content.arrayBuffer());
        this.updateProgress(100, `已导出到: ${pathToSave}`);
        return pathToSave;
      } else if (saveFile) {
        // 普通浏览器环境下载文件，仅当saveFile为true时
        console.log('[DEBUG] 自动保存文件');
        console.log('[VueProjectExportService] 自动保存文件');
        saveAs(content, `${projectName}.zip`);
        this.updateProgress(100, '导出完成，已保存文件');
      } else {
        // 不自动保存，仅返回blob
        console.log('[DEBUG] 不自动保存文件，仅返回blob');
        console.log('[VueProjectExportService] 不自动保存文件，仅返回blob');
        this.updateProgress(100, '导出完成，未保存文件');
      }

      // 始终返回content blob以便外部可能的后续使用
      return content;
    } catch (error) {
      console.error('[DEBUG] 导出Vue项目失败:', error);
      console.error('[VueProjectExportService] 导出Vue项目失败:', error);
      this.updateProgress(0, `导出失败: ${error.message}`);
      ElMessage.error('导出Vue项目失败: ' + error.message);
      throw error;
    } finally {
      // 重置状态
      setTimeout(() => {
        this.isExporting = false;
      }, 2000);
    }
  }

  /**
   * 收集画布上使用到的组件类型
   * @param {Array} components 组件数组
   */
  collectUsedComponentTypes(components) {
    console.log('[DEBUG] 开始收集画布上使用的组件类型，组件数量:', components.length);
    
    // 确定页面上使用了哪些组件类型
    const usedComponentTypes = new Set();

    const processComponent = (comp) => {
      console.log('[DEBUG] 处理组件:', comp.id, '类型:', comp.type);
      
      if (comp.type.startsWith('ew-')) {
        usedComponentTypes.add(comp.type);
        console.log('[DEBUG] 添加自定义组件类型:', comp.type);
      }

      // 处理嵌套组件
      if (comp.children && comp.children.length > 0) {
        console.log('[DEBUG] 处理组件子元素, 数量:', comp.children.length);
        comp.children.forEach(child => {
          processComponent(child);
        });
      }
    };

    components.forEach(comp => {
      processComponent(comp);
    });

    // 保存使用的组件类型用于后续导出
    this.usedComponentTypes = Array.from(usedComponentTypes);
    console.log('[DEBUG] 收集完成，使用的组件类型:', this.usedComponentTypes);
    console.log('[VueProjectExportService] 已收集使用的组件类型:', this.usedComponentTypes);
  }

  /**
   * 生成项目基本结构
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   */
  generateProjectStructure(zip, projectName) {
    // 创建目录结构
    const dirs = [
      'public',
      'src/assets',
      'src/components',
      'src/components/basic',
      'src/components/business',
      'src/components/custom',
      'src/router',
      'src/stores',
      'src/views',
      'src/utils'
    ];

    dirs.forEach(dir => {
      zip.folder(`${projectName}/${dir}`);
    });

    // 创建入口文件
    zip.file(`${projectName}/src/main.js`, this.generateMainJs());
    zip.file(`${projectName}/src/App.vue`, this.generateAppVue());
    zip.file(`${projectName}/src/router/index.js`, this.generateRouterJs());
    zip.file(`${projectName}/src/stores/index.js`, this.generateStoreJs());

    // index.html 应该放在项目根目录，而不是public目录
    zip.file(`${projectName}/index.html`, this.generateIndexHtml());
  }

  /**
   * 生成主页面Vue文件
   * @param {string} projectName 项目名称
   * @param {Object} canvasData 画布数据
   * @returns {string} MainPage.vue 内容
   */
  generateMainPageVue(projectName, canvasData) {
    try {
      const { components, componentStyles, componentProps, canvasStyle } = canvasData;

      // 打印原始数据结构以便调试
      console.log('[DEBUG] 原始componentProps结构:', JSON.stringify(componentProps, null, 2));
      console.log('[DEBUG] 画布样式:', JSON.stringify(canvasStyle, null, 2));

      // 组件类型到组件名的映射
      const componentTypeToName = {};

      // 预处理组件类型到组件名的映射
      for (const type of this.usedComponentTypes) {
        // 组件名称转换：ew-button -> EwButton
        const nameParts = type.split('-');
        const pascalComponentName = nameParts.map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');
        componentTypeToName[type] = pascalComponentName;
      }

      // 彻底修正componentProps结构，完全去除嵌套
      const fixedComponentProps = {};
      for (const [componentId, props] of Object.entries(componentProps)) {
        // 检查并提取实际的数据值
        if (props && props.datas) {
          if (props.datas.datas) {
            // 如果存在嵌套的datas.datas结构，直接使用内层datas
            fixedComponentProps[componentId] = { datas: props.datas.datas };
            console.log(`[DEBUG] 修复组件 ${componentId} 的嵌套datas结构`);
          } else {
            // 如果没有嵌套，保留原始datas
            fixedComponentProps[componentId] = { datas: props.datas };
          }
        } else {
          // 如果没有datas属性，保留原始结构
          fixedComponentProps[componentId] = props || {};
          console.log(`[DEBUG] 组件 ${componentId} 没有datas属性，保留原始结构`);
        }
      }

      console.log('[DEBUG] 修复后的componentProps结构:', JSON.stringify(fixedComponentProps, null, 2));

      // 生成组件模板 - 传递修正后的props
      const componentTemplate = this.generateComponentTemplate(components, fixedComponentProps);

      // 提取画布尺寸和样式
      const canvasWidth = canvasStyle.width || '600px';
      const canvasHeight = canvasStyle.height || '400px';
      const canvasBgColor = canvasStyle.backgroundColor || '#ffffff';
      const canvasBorderWidth = canvasStyle.borderWidth || 1;
      const canvasBorderStyle = canvasStyle.borderStyle || 'solid';
      const canvasBorderColor = canvasStyle.borderColor || '#cccccc';
      const canvasBorderRadius = canvasStyle.borderRadius || 4;

      // 生成样式和属性的JSON字符串，保持缩进格式
      const styleJson = JSON.stringify(componentStyles, null, 2);
      const propsJson = JSON.stringify(fixedComponentProps, null, 2);
      const canvasStyleJson = JSON.stringify(canvasStyle, null, 2);

      // 生成完整文件内容
      const pageContent = `<template>
  <div class="main-page">
    <div class="canvas-container" :style="canvasStyle">
${componentTemplate}
    </div>
  </div>
</template>

<script>
import { ref, reactive } from "vue";
import { ElButton, ElInput, ElSelect, ElTable, ElTableColumn, ElForm, ElFormItem, ElRadio, ElRadioGroup, ElCheckbox, ElCheckboxGroup, ElSwitch, ElDatePicker, ElTimePicker, ElSlider, ElInputNumber, ElTag, ElAlert, ElCard, ElDivider, ElImage, ElRow, ElCol } from "element-plus";
import "element-plus/dist/index.css";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";

// 导入自定义组件库 (注册了所有组件)
import EasyWindowComponents from "../components";

export default {
  name: "MainPage",
  components: {
    ...EasyWindowComponents
  },
  
  setup() {
    // 组件样式
    const componentStyles = reactive(${styleJson});
    
    // 组件属性
    const componentProps = reactive(${propsJson});
    
    // 画布样式
    const canvasStyle = reactive(${canvasStyleJson});
    
    return {
      componentStyles,
      componentProps,
      canvasStyle
    };
  }
}
</script>

<style scoped>
.main-page {
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  min-height: 100vh;
  box-sizing: border-box;
  background-color: #f5f7fa;
  margin: 0;
  overflow: auto;
}

.canvas-container {
  width: ${canvasWidth};
  height: ${canvasHeight};
  position: relative;
  background-color: ${canvasBgColor};
  border: ${canvasBorderWidth}px ${canvasBorderStyle} ${canvasBorderColor};
  border-radius: ${canvasBorderRadius}px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.exported-component {
  position: absolute;
}
</style>`;

      return pageContent;
    } catch (error) {
      console.error('生成主页面失败:', error);
      throw error;
    }
  }

  /**
   * 分析组件依赖关系
   * @param {Array} components 组件数组
   */
  async analyzeComponentDependencies(components) {
    const analyzeComponent = async (component) => {
      // 记录组件类型
      this.componentsMap.set(component.id, component.type);

      // 根据组件类型添加依赖
      if (component.type.startsWith('el-')) {
        // Element Plus组件
        this.componentDependencies.add('element-plus');
      } else if (component.type.startsWith('ew-')) {
        // 自定义组件（Easy Window组件）- 使用Element Plus作为基础
        this.componentDependencies.add('element-plus');
        // 不再添加不存在的easy-window-components依赖
      }

      // 处理子组件
      if (component.children && component.children.length > 0) {
        for (const child of component.children) {
          await analyzeComponent(child);
        }
      }
    };

    // 分析所有根组件
    for (const component of components) {
      await analyzeComponent(component);
    }
  }

  /**
   * 处理组件结构使其适合Vue渲染
   * @param {Array} components 组件数组
   */
  processComponentsForVue(components) {
    const processComponent = (component) => {
      // 保存原始组件类型
      component.originalType = component.type;

      // 不再转换组件类型，保持原始类型以便正确处理
      // 在模板生成时会根据类型映射到适当的组件

      // 将style对象转换为Vue绑定格式
      if (component.style) {
        // 复制原始样式，保留原始数据结构
        const originalStyle = { ...component.style };
        component.style = originalStyle;
      }

      // 处理事件绑定
      if (component.events) {
        const processedEvents = {};
        Object.entries(component.events).forEach(([event, handler]) => {
          // 将事件处理程序转换为方法引用
          const methodName = `handle${component.id}${event.charAt(0).toUpperCase() + event.slice(1)}`;
          processedEvents[event] = methodName;
        });
        component.events = processedEvents;
      }

      // 递归处理子组件
      if (component.children && component.children.length > 0) {
        component.children.forEach(processComponent);
      }
    };

    // 处理所有根组件
    components.forEach(processComponent);
  }

  /**
   * 生成组件模板代码
   * @param {Array} components 组件数组
   * @param {Object} fixedComponentProps 修复后的组件属性
   * @returns {string} 模板代码
   */
  generateComponentTemplate(components, fixedComponentProps = null) {
    // 组件类型到导出组件名的映射
    const componentTypeToName = {};

    // 首先预处理组件类型到组件名的映射
    for (const [type, path] of Object.entries(this.componentTypeToPathMap)) {
      // 组件名称转换：ew-button -> EwButton
      const nameParts = type.split('-');
      const componentName = nameParts.map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');
      componentTypeToName[type] = componentName;
    }

    const generateTemplate = (component, indent = 6) => {
      const indentStr = ' '.repeat(indent);

      // 处理事件绑定
      let eventBindings = '';
      if (component.events) {
        Object.entries(component.events).forEach(([event, methodName]) => {
          eventBindings += `\n${indentStr}  @${event}="${methodName}"`;
        });
      }

      // 确定使用哪种组件
      let componentType = component.type;
      let isCustomComponent = false;
      let componentTagName = componentType;

      // 如果是自定义组件，使用映射的组件名作为标签名
      if (component.type.startsWith('ew-') && componentTypeToName[component.type]) {
        componentTagName = componentTypeToName[component.type]; // PascalCase组件名：EwButton
        isCustomComponent = true;
      }

      // 生成模板
      let template;

      if (isCustomComponent) {
        // 使用修正后的props结构，确保不会出现嵌套的datas
        template = `${indentStr}<${componentTagName}
${indentStr}  id="${component.id}"
${indentStr}  class="exported-component"
${indentStr}  :datas="componentProps['${component.id}'].datas"
${indentStr}  :style="componentStyles['${component.id}']"${eventBindings}
${indentStr}>\n`;
      } else {
        // 使用普通组件绑定 (Element Plus组件)
        template = `${indentStr}<${componentTagName}
${indentStr}  id="${component.id}"
${indentStr}  class="exported-component"
${indentStr}  :style="componentStyles['${component.id}']"
${indentStr}  v-bind="componentProps['${component.id}'].datas"${eventBindings}
${indentStr}>\n`;
      }

      // 处理子组件
      if (component.children && component.children.length > 0) {
        template += `${indentStr}  <!-- 子组件 -->\n`;
        component.children.forEach(child => {
          template += generateTemplate(child, indent + 2);
        });
        template += `${indentStr}</${componentTagName}>\n`;
      } else {
        template += `${indentStr}</${componentTagName}>\n`;
      }

      return template;
    };

    let result = '';
    components.forEach(component => {
      result += generateTemplate(component);
    });

    return result;
  }

  /**
   * 生成组件脚本代码
   * @param {Array} components 组件数组
   * @param {Object} options 配置选项
   * @returns {string} 脚本代码
   */
  generateComponentScript(components, options) {
    // 收集所有组件事件处理方法
    const eventMethods = [];
    const dataProperties = {};
    // 记录使用的自定义组件类型
    const usedComponentTypes = new Set();

    const collectMethods = (component) => {
      if (component.events) {
        Object.entries(component.events).forEach(([event, methodName]) => {
          // 从原始事件获取处理程序代码
          const handlerCode = component.events[event];
          eventMethods.push(`
          ${methodName}(event) {
            console.log('Event ${event} triggered on ${component.id}', event);
            ${handlerCode || '// 未定义事件处理程序'}
          }`);
        });
      }

      // 处理组件属性中的函数
      if (component.props && component.props.datas) {
        Object.entries(component.props.datas).forEach(([key, value]) => {
          if (typeof value === 'string' && value.includes('function')) {
            const methodName = `${key}${component.id}`;
            const functionBody = value.replace(/function\s*\([^)]*\)\s*{/, '').replace(/}$/, '').trim();
            eventMethods.push(`
    ${methodName}(value) {
      ${functionBody}
    }`);
          }
        });
      }

      // 收集组件props
      dataProperties[component.id] = component.props || {};

      // 记录使用的自定义组件类型
      if (component.type && component.type.startsWith('ew-')) {
        usedComponentTypes.add(component.type);
      }

      // 递归处理子组件
      if (component.children && component.children.length > 0) {
        component.children.forEach(collectMethods);
      }
    };

    // 收集所有组件的方法和数据
    components.forEach(collectMethods);

    // 收集所有组件样式
    const componentStyles = {};

    const collectStyles = (component) => {
      componentStyles[component.id] = component.style || {};

      if (component.children && component.children.length > 0) {
        component.children.forEach(collectStyles);
      }
    };

    components.forEach(collectStyles);

    // 生成导入部分
    let imports = 'import { ref, reactive } from "vue";\n';

    // 添加Element Plus组件导入
    if (this.componentDependencies.has('element-plus')) {
      imports += 'import { ElButton, ElInput, ElSelect, ElTable, ElTableColumn, ElForm, ElFormItem, ElRadio, ElRadioGroup, ElCheckbox, ElCheckboxGroup, ElSwitch, ElDatePicker, ElTimePicker, ElSlider, ElInputNumber, ElTag, ElAlert, ElCard, ElDivider, ElImage, ElRow, ElCol } from "element-plus";\n';
      imports += 'import "element-plus/dist/index.css";\n';
      imports += 'import * as ElementPlusIconsVue from "@element-plus/icons-vue";\n';
    }

    // 添加自定义组件导入
    if (usedComponentTypes.size > 0) {
      // 使用全局组件导入方式
      imports += '\n// 导入自定义组件\n';
      imports += 'import EasyWindowComponents from "../components";\n';
    }

    // 提取画布样式
    const canvasStyle = options.canvasStyle || {
      backgroundColor: "#ffffff",
      borderWidth: 1,
      borderStyle: "solid",
      borderColor: "#ddd",
      borderRadius: 4
    };

    // 生成完整的script部分
    const scriptContent = `${imports}

export default {
  name: "MainPage",
  
  setup() {
    // 组件样式
    const componentStyles = reactive(${JSON.stringify(componentStyles, null, 2)});
    
    // 组件属性
    const componentProps = reactive(${JSON.stringify(dataProperties, null, 2)});
    
    // 画布样式
    const canvasStyle = reactive({
      width: "${options.width}px",
      height: "${options.height}px",
      position: "relative",
      backgroundColor: "${canvasStyle.backgroundColor}",
      border: "${canvasStyle.borderWidth}px ${canvasStyle.borderStyle} ${canvasStyle.borderColor}",
      borderRadius: "${canvasStyle.borderRadius}px",
      margin: "0 auto",
      overflow: "hidden"
    });
    
    ${eventMethods.join(',\n')}
    
    return {
      componentStyles,
      componentProps,
      canvasStyle
    };
  }
}`;

    return scriptContent;
  }

  /**
   * 生成组件样式代码
   * @param {Object} options 配置选项
   * @returns {string} 样式代码
   */
  generateComponentStyle(options) {
    // 获取画布样式
    const canvasStyle = options.canvasStyle || {
      backgroundColor: "#ffffff",
      borderWidth: 1,
      borderStyle: "solid",
      borderColor: "#ddd",
      borderRadius: 4
    };

    return `.main-page {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 20px;
  box-sizing: border-box;
}

.canvas-container {
  width: ${options.width}px;
  height: ${options.height}px;
  position: relative;
  background-color: ${canvasStyle.backgroundColor};
  border: ${canvasStyle.borderWidth}px ${canvasStyle.borderStyle} ${canvasStyle.borderColor};
  border-radius: ${canvasStyle.borderRadius}px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.exported-component {
  position: absolute;
}`;
  }

  /**
   * 生成package.json
   * @param {string} projectName 项目名称
   * @returns {string} 生成的package.json内容
   */
  generatePackageJson(projectName) {
    const dependencies = {
      "vue": "^3.3.4",
      "vue-router": "^4.2.4",
      "pinia": "^2.1.6",
      // 默认添加Element Plus依赖，因为在main.js中已经导入
      "element-plus": "^2.3.12",
      "@element-plus/icons-vue": "^2.1.0"
    };

    const packageJson = {
      "name": projectName,
      "version": "0.1.0",
      "private": true,
      "type": "module", // 确保设置正确的类型，Vite使用ESM
      "scripts": {
        "dev": "vite",
        "build": "vite build",
        "preview": "vite preview"
      },
      "dependencies": dependencies,
      "devDependencies": {
        "@vitejs/plugin-vue": "^4.3.4",
        "vite": "^4.4.9",
        "terser": "^5.19.2", // 添加terser依赖
        "less": "^4.1.3" // 添加Less预处理器依赖
      }
    };

    return JSON.stringify(packageJson, null, 2);
  }

  /**
   * 生成vite.config.js
   * @param {string} projectName 项目名称
   * @returns {string} vite.config.js内容
   */
  generateViteConfig(projectName) {
    return `import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'

export default defineConfig({
  plugins: [vue()],
  root: './', // 确保根目录配置正确
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  server: {
    port: 3000,
    open: true
  },
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    emptyOutDir: true,
    minify: 'terser', // 可以使用 'esbuild' 作为替代
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
    },
    // 如果terser安装失败，自动回退到esbuild
    rollupOptions: {
      onwarn(warning, defaultHandler) {
        // 忽略关于terser的警告
        if (warning.message && warning.message.includes('terser')) {
          return;
        }
        defaultHandler(warning);
      }
    }
  }
})`;
  }

  /**
   * 生成入口main.js
   * @returns {string} main.js内容
   */
  generateMainJs() {
    return `import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'
import router from './router'
import EasyWindowComponents from './components'

const app = createApp(App)

// 注册所有Element Plus图标组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.use(createPinia())
app.use(router)
app.use(ElementPlus)
app.use(EasyWindowComponents) // 注册自定义组件

app.mount('#app')`;
  }

  /**
   * 生成App.vue
   * @returns {string} App.vue内容
   */
  generateAppVue() {
    return `<template>
  <router-view />
</template>

<style>
body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
}
</style>`;
  }

  /**
   * 生成router/index.js
   * @returns {string} router/index.js内容
   */
  generateRouterJs() {
    return `import { createRouter, createWebHashHistory } from 'vue-router'
import MainPage from '../views/MainPage.vue'

const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: MainPage
    }
  ]
})

export default router`;
  }

  /**
   * 生成stores/index.js
   * @returns {string} stores/index.js内容
   */
  generateStoreJs() {
    return `import { defineStore } from 'pinia'

export const useMainStore = defineStore('main', {
  state: () => ({
    
  }),
  getters: {
    
  },
  actions: {
    
  }
})`;
  }

  /**
   * 生成public/index.html
   * @returns {string} index.html内容
   */
  generateIndexHtml() {
    return `<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Easy Window 导出项目</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>`;
  }

  /**
   * 生成项目根目录文件
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   */
  generateRootFiles(zip, projectName) {
    // 生成.gitignore
    zip.file(`${projectName}/.gitignore`, `node_modules
.DS_Store
dist
dist-ssr
*.local`);

    // 生成README.md
    zip.file(`${projectName}/README.md`, this.generateReadme(projectName));
  }

  /**
   * 生成后端API结构
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   */
  generateBackendStructure(zip, projectName) {
    // 创建后端目录
    zip.folder(`${projectName}/server`);
    zip.folder(`${projectName}/server/routes`);
    zip.folder(`${projectName}/server/controllers`);
    zip.folder(`${projectName}/server/models`);

    // 生成后端入口文件
    zip.file(`${projectName}/server/index.js`, this.generateServerIndexJs());

    // 生成package.json，加入后端依赖
    const packageJson = JSON.parse(zip.file(`${projectName}/package.json`).async('string'));
    packageJson.dependencies = {
      ...packageJson.dependencies,
      "express": "^4.18.2",
      "cors": "^2.8.5",
      "body-parser": "^1.20.2"
    };

    // 为服务器添加单独的package.json，以便后端能够以CJS模式运行
    const serverPackageJson = {
      "name": `${projectName}-server`,
      "version": "1.0.0",
      "type": "module", // 使用ESM模式
      "private": true,
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^4.18.2",
        "cors": "^2.8.5",
        "body-parser": "^1.20.2"
      }
    };

    zip.file(`${projectName}/server/package.json`, JSON.stringify(serverPackageJson, null, 2));

    // 更新主项目的scripts
    packageJson.scripts = {
      ...packageJson.scripts,
      "server": "cd server && npm install && node index.js",
      "dev:full": "concurrently \"npm run dev\" \"npm run server\""
    };
    packageJson.devDependencies = {
      ...packageJson.devDependencies,
      "concurrently": "^8.2.1"
    };

    zip.file(`${projectName}/package.json`, JSON.stringify(packageJson, null, 2));

    // 生成示例API路由
    zip.file(`${projectName}/server/routes/api.js`, this.generateApiRouteJs());

    // 生成示例控制器
    zip.file(`${projectName}/server/controllers/dataController.js`, this.generateDataControllerJs());
  }

  /**
   * 生成后端入口文件
   * @returns {string} server/index.js内容
   */
  generateServerIndexJs() {
    return `import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import apiRoutes from './routes/api.js';

const app = express();
const PORT = process.env.PORT || 3001;

// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 路由
app.use('/api', apiRoutes);

// 启动服务器
app.listen(PORT, () => {
  console.log(\`服务器运行在 http://localhost:\${PORT}\`);
});`;
  }

  /**
   * 生成API路由文件
   * @returns {string} routes/api.js内容
   */
  generateApiRouteJs() {
    return `import express from 'express';
import * as dataController from '../controllers/dataController.js';

const router = express.Router();

// 获取数据列表
router.get('/data', dataController.getAllData);

// 获取单个数据项
router.get('/data/:id', dataController.getDataById);

// 创建数据
router.post('/data', dataController.createData);

// 更新数据
router.put('/data/:id', dataController.updateData);

// 删除数据
router.delete('/data/:id', dataController.deleteData);

export default router;`;
  }

  /**
   * 生成数据控制器
   * @returns {string} controllers/dataController.js内容
   */
  generateDataControllerJs() {
    return `// 模拟数据存储
let dataStore = [
  { id: 1, name: '示例项目1', description: '这是第一个示例项目' },
  { id: 2, name: '示例项目2', description: '这是第二个示例项目' }
];

// 获取所有数据
export const getAllData = (req, res) => {
  res.json({
    success: true,
    data: dataStore
  });
};

// 根据ID获取数据
export const getDataById = (req, res) => {
  const id = parseInt(req.params.id);
  const item = dataStore.find(i => i.id === id);
  
  if (!item) {
    return res.status(404).json({
      success: false,
      message: '找不到指定ID的数据'
    });
  }
  
  res.json({
    success: true,
    data: item
  });
};

// 创建数据
export const createData = (req, res) => {
  const { name, description } = req.body;
  
  if (!name) {
    return res.status(400).json({
      success: false,
      message: '名称字段是必需的'
    });
  }
  
  const newId = dataStore.length > 0 ? Math.max(...dataStore.map(i => i.id)) + 1 : 1;
  const newItem = {
    id: newId,
    name,
    description: description || ''
  };
  
  dataStore.push(newItem);
  
  res.status(201).json({
    success: true,
    data: newItem
  });
};

// 更新数据
export const updateData = (req, res) => {
  const id = parseInt(req.params.id);
  const { name, description } = req.body;
  
  const index = dataStore.findIndex(i => i.id === id);
  if (index === -1) {
    return res.status(404).json({
      success: false,
      message: '找不到指定ID的数据'
    });
  }
  
  // 更新数据
  if (name) dataStore[index].name = name;
  if (description) dataStore[index].description = description;
  
  res.json({
    success: true,
    data: dataStore[index]
  });
};

// 删除数据
export const deleteData = (req, res) => {
  const id = parseInt(req.params.id);
  const initialLength = dataStore.length;
  
  dataStore = dataStore.filter(i => i.id !== id);
  
  if (dataStore.length === initialLength) {
    return res.status(404).json({
      success: false,
      message: '找不到指定ID的数据'
    });
  }
  
  res.json({
    success: true,
    message: '数据已成功删除'
  });
};`;
  }

  /**
   * 生成README.md文件，包含组件使用说明和文档
   * @returns {string} README.md内容
   */
  generateReadme(projectName) {
    return `# ${projectName}

这是使用 Easy Window 设计器导出的Vue项目。

## 项目设置

\`\`\`bash
# 安装依赖
npm install

# 开发模式启动
npm run dev

# 构建生产版本
npm run build
\`\`\`

## 项目结构

- \`src/views/MainPage.vue\`: 导出的主页面组件
- \`src/components/\`: 导出的组件库
- \`src/components/basic/\`: 基础组件，如按钮、输入框等
- \`src/router/index.js\`: 路由配置
- \`src/stores/index.js\`: Pinia 状态管理

## 组件使用方式

所有组件均保持与原始Easy Window设计器中相同的功能和属性结构，使用时只需传递datas对象。

### 按钮组件 (EwButton)

\`\`\`vue
<EwButton :datas="{
  buttonText: '按钮文本',
  type: 'primary',
  size: 'default',
  plain: false,
  round: false,
  circle: false,
  disabled: false,
  icon: 'Edit',
  iconPosition: 'left',
  width: '100%',
  height: '100%'
}" />
\`\`\`

### 输入框组件 (EwInput)

\`\`\`vue
<EwInput :datas="{
  placeholder: '请输入内容',
  value: '',
  type: 'text',
  maxlength: '',
  disabled: false,
  clearable: true,
  showPassword: false,
  prefixIcon: '',
  suffixIcon: '',
  rows: 2,
  width: '100%',
  height: '100%',
  labelText: '标签',
  labelWidth: '80px',
  required: false
}" />
\`\`\`

## 自定义与扩展

### 添加新组件

如需添加新的组件，只需在 \`src/components/basic/\` 目录下创建新的 Vue 组件文件，并在 \`src/components/index.js\` 中注册即可。

### 修改现有组件

所有组件都设计为可扩展的，您可以直接修改组件文件来满足特定需求。

## 注意事项

该项目是由 Easy Window 自动生成的，可以根据需要进行修改和扩展。
更多组件会在后续版本中添加。
`;
  }

  /**
   * 保存ZIP文件
   * @param {Blob} blob ZIP文件Blob
   * @param {string} filename 文件名
   */
  saveZipFile(blob, filename) {
    saveAs(blob, filename);
  }

  /**
   * 从应用程序中获取组件并复制到导出项目
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   * @param {Set<string>} usedComponentTypes 使用的组件类型集合
   * @returns {Promise<void>}
   */
  async copyComponentsToExport(zip, projectName, usedComponentTypes) {
    try {
      console.log('[DEBUG] 开始复制组件到导出项目, 需要处理的组件类型:', usedComponentTypes);
      console.log('[DEBUG] componentTypeToPathMap:', this.componentTypeToPathMap);
      console.log('[VueProjectExportService] 开始复制组件到导出项目:', usedComponentTypes);

      // 创建组件目录结构 - 确保所有需要的目录都存在
      zip.folder(`${projectName}/src/components/basic`);
      zip.folder(`${projectName}/src/components/business`);
      zip.folder(`${projectName}/src/components/custom`);

      // 收集组件信息
      const indexImports = [];
      const indexExports = [];
      const indexRegistrations = [];
      const failedComponents = []; // 记录读取失败的组件

      // 处理每个使用到的组件
      for (const componentType of usedComponentTypes) {
        // 查找组件映射路径
        const relativePath = this.componentTypeToPathMap[componentType];
        console.log(`[DEBUG] 处理组件: ${componentType}, 映射路径: ${relativePath}`);
        
        if (!relativePath) {
          console.warn(`[DEBUG] 未找到组件类型 "${componentType}" 的路径映射，跳过该组件`);
          console.warn(`[VueProjectExportService] 未找到组件类型 "${componentType}" 的路径映射，跳过该组件`);
          failedComponents.push(componentType);
          continue;
        }

        // 解析路径信息
        const [dirName, componentName] = relativePath.split('/');
        if (!dirName || !componentName) {
          console.warn(`[DEBUG] 无效的组件路径: ${relativePath}，跳过该组件`);
          console.warn(`[VueProjectExportService] 无效的组件路径: ${relativePath}，跳过该组件`);
          failedComponents.push(componentType);
          continue;
        }

        // 组件名称转换：ew-button -> EwButton
        const nameParts = componentType.split('-');
        const pascalComponentName = nameParts.map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');

        console.log(`[DEBUG] 处理组件: ${componentType} (${pascalComponentName}) 从目录: ${dirName}`);
        console.log(`[VueProjectExportService] 处理组件: ${componentType} (${pascalComponentName}) 从目录: ${dirName}`);

        // 使用相对路径导入组件内容
        let componentContent = null;
        try {
          console.log(`[DEBUG] 尝试动态导入组件 (raw)...`);
          
          // 使用相对路径导入 (这是唯一保留的方法)
          const importPath = `../components/library/${dirName}/${componentName}/index.vue?raw`;
          console.log(`[DEBUG] 尝试导入路径: ${importPath}`);
          const raw = await import(/* @vite-ignore */ importPath);
          if (raw && raw.default) {
            componentContent = raw.default;
            console.log(`[DEBUG] 成功通过相对路径导入, 内容长度:`, componentContent.length);
          }
        } catch (error) {
          console.warn(`[DEBUG] 组件导入失败:`, error.message);
        }
        
        // 如果仍然无法获取组件内容，创建一个备用组件
        if (!componentContent) {
          console.warn(`[DEBUG] 无法获取组件 ${pascalComponentName} 的内容，创建简单替代组件`);
          componentContent = this.generateFallbackComponent(pascalComponentName, componentType);
        }
        
        if (componentContent) {
          // 处理源组件内容，移除设计时功能，保留运行时功能
          componentContent = this.processComponentContent(componentContent, pascalComponentName);
          console.log(`[DEBUG] 已处理组件内容，准备添加到ZIP`);

          // 添加到ZIP - 使用Pascal命名法的组件文件名
          zip.file(`${projectName}/src/components/${dirName}/${pascalComponentName}.vue`, componentContent);
          console.log(`[DEBUG] 已添加组件到ZIP: ${projectName}/src/components/${dirName}/${pascalComponentName}.vue`);

          // 添加到索引信息
          indexImports.push(`import ${pascalComponentName} from './${dirName}/${pascalComponentName}.vue';`);
          indexExports.push(pascalComponentName);

          // 在组件注册中，同时注册PascalCase和kebab-case形式的名称
          indexRegistrations.push(`  app.component('${pascalComponentName}', ${pascalComponentName});`);
          indexRegistrations.push(`  app.component('${componentType}', ${pascalComponentName});`);
          console.log(`[DEBUG] 已添加组件 ${pascalComponentName} 到注册列表`);
        } else {
          console.warn(`[DEBUG] 组件 ${pascalComponentName} 内容为空，跳过添加到ZIP`);
          failedComponents.push(componentType);
        }
      }

      // 输出失败组件的汇总信息
      if (failedComponents.length > 0) {
        console.warn(`[DEBUG] 以下组件处理失败: ${failedComponents.join(', ')}`);
        console.warn(`[VueProjectExportService] 以下组件处理失败: ${failedComponents.join(', ')}`);
        ElMessage.warning(`有 ${failedComponents.length} 个组件无法导出`);
      }

      // 生成组件索引文件
      if (indexImports.length > 0) {
        const indexContent = `// 自动生成的组件索引文件
${indexImports.join('\n')}

// 导出所有组件
export {
  ${indexExports.join(',\n  ')}
};

// 批量注册所有组件
export default {
  install(app) {
${indexRegistrations.join('\n')}
  }
}`;

        // 添加到ZIP
        zip.file(`${projectName}/src/components/index.js`, indexContent);
        console.log(`[DEBUG] 已生成index.js文件，组件数量: ${indexExports.length}`);
        console.log(`[VueProjectExportService] 组件导出完成，已生成index.js文件，包含${indexExports.length}个组件`);
      } else {
        // 没有找到任何组件，抛出错误
        console.error('[DEBUG] 未找到任何可用组件');
        console.error('[VueProjectExportService] 未找到任何可用组件');
        throw new Error('未能导出任何组件，请确保组件库路径正确');
      }

    } catch (error) {
      console.error('[DEBUG] 复制组件到导出项目失败:', error);
      console.error('[VueProjectExportService] 复制组件到导出项目失败:', error);
      ElMessage.error('复制组件失败: ' + error.message);
      throw error;
    }
  }
  
  /**
   * 生成备用组件内容
   * @param {string} componentName 组件名称 (Pascal命名法)
   * @param {string} componentType 组件类型 (kebab命名法，例如ew-button)
   * @returns {string} 组件内容
   */
  generateFallbackComponent(componentName, componentType) {
    return `<template>
  <div class="${componentType}-container">
    <slot name="default">
      <div class="${componentType}-fallback">
        <el-alert
          title="组件内容丢失"
          type="warning"
          :closable="false"
          description="此组件在导出过程中无法获取源代码。这是自动生成的替代内容。"
        />
      </div>
    </slot>
  </div>
</template>

<script>
export default {
  name: '${componentName}',
  props: {
    datas: {
      type: Object,
      default: () => ({})
    }
  },
  setup(props) {
    console.warn('使用备用组件替代 ${componentName}');
    return {};
  }
}
</script>

<style scoped>
.${componentType}-container {
  display: block;
  width: 100%;
  height: 100%;
}

.${componentType}-fallback {
  padding: 10px;
  border: 1px dashed #f56c6c;
  border-radius: 4px;
}
</style>`;
  }

  /**
   * 更新导出进度
   * @param {number} progress 进度百分比
   * @param {string} message 进度消息
   */
  updateProgress(progress, message) {
    this.progress = progress;
    this.exportMessage = message;
    console.log(`[VueProjectExportService] 导出进度: ${progress}% - ${message}`);
  }

  /**
   * 复制静态资源
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   */
  async copyStaticAssets(zip, projectName) {
    try {
      // 复制图标 - 使用一个非常简单的favicon图标
      // 这里使用了正确格式的base64编码数据
      const faviconBase64 = 'AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAANjY2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAEAEAEAEAAQABAQEBAAEAAQABAAABAQEAAAEAEAABAREBEQARABEAEQAREBEAARAAARAREREAAREAEQARABEQAREAAQABEAEBAAERAQABAQEAAAEAAAEAAQAAAAEAAQEBAQABAAEAAQABABEAEAEAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==';

      // 使用Uint8Array处理base64数据，避免字符串编码问题
      const binaryString = atob(faviconBase64);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }

      // 添加为二进制数据
      zip.file(`${projectName}/public/favicon.ico`, bytes.buffer, { binary: true });

      // 复制其他静态资源
      zip.file(`${projectName}/public/robots.txt`, 'User-agent: *\nDisallow:');

      // 添加CSS变量
      zip.file(`${projectName}/src/assets/variables.css`, `:root {
  --primary-color: #409eff;
  --success-color: #67c23a;
  --warning-color: #e6a23c;
  --danger-color: #f56c6c;
  --info-color: #909399;
  
  --text-color: #303133;
  --border-color: #dcdfe6;
  --background-color: #f8f9fa;
}
`);
    } catch (error) {
      console.error('[VueProjectExportService] 复制静态资源失败:', error);
      // 如果图标复制失败，尝试使用备用方法
      try {
        // 创建一个最小的1x1像素图标，作为备用方案
        const minimalIcon = new Uint8Array([0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 2, 1, 0, 0]);
        zip.file(`${projectName}/public/favicon.ico`, minimalIcon.buffer, { binary: true });
      } catch (backupError) {
        console.error('[VueProjectExportService] 备用图标也失败:', backupError);
        // 最后的备用方案：完全跳过图标
      }
    }
  }

  /**
   * 生成配置文件
   * @param {JSZip} zip JSZip实例
   * @param {string} projectName 项目名称
   * @param {boolean} includeElectron 是否包含Electron
   * @param {boolean} includeBackend 是否包含后端
   */
  generateConfigFiles(zip, projectName, includeElectron, includeBackend) {
    // 生成package.json
    zip.file(`${projectName}/package.json`, this.generatePackageJson(projectName));

    // 生成vite.config.js
    zip.file(`${projectName}/vite.config.js`, this.generateViteConfig(projectName));

    // 生成根目录文件
    this.generateRootFiles(zip, projectName);

    // 如果包含后端，生成后端结构
    if (includeBackend) {
      this.generateBackendStructure(zip, projectName);
    }

    // 如果包含Electron，生成Electron相关文件
    if (includeElectron) {
      // TODO: 生成Electron相关文件
      // 这可能需要额外的方法来实现
      console.log('[VueProjectExportService] Electron支持暂未实现');
    }
  }

  /**
   * 处理组件内容，移除设计时功能，保留运行时功能
   * @param {string} content 组件内容
   * @param {string} componentName 组件名称（可选，用于重命名）
   * @returns {string} 处理后的内容
   */
  processComponentContent(content, componentName) {
    // 处理组件内容，移除设计时特有的代码，保留运行时需要的代码

    // 1. 替换组件名为Pascal命名
    content = content.replace(/<script[\s\S]*?>([\s\S]*?)<\/script>/g, (match, scriptContent) => {
      // 修改组件名
      const updatedScript = scriptContent.replace(
        /name\s*:\s*['"].*?['"]/,
        `name: '${componentName}'`
      );

      return match.replace(scriptContent, updatedScript);
    });

    // 2. 移除仅用于设计时的属性和方法
    content = content.replace(/\/\/ @design-time-only[\s\S]*?\/\/ @design-time-end/g, '');

    // 3. 保留原始props定义，确保结构完整性
    content = content.replace(/props\s*:\s*{[\s\S]*?},/g, (match) => {
      // 保留原始props，不进行简化
      return match;
    });
    
    // 4. 修正脚本中的语法错误
    content = content.replace(/<script>([\s\S]*?)<\/script>/g, (match, scriptContent) => {
      // 检查script标签中的内容是否有语法错误
      
      // 检查是否缺少右括号，确保export default结构完整
      if ((scriptContent.match(/\{/g) || []).length > (scriptContent.match(/\}/g) || []).length) {
        // 在最后一个右括号前添加缺少的右括号
        const lastBraceIndex = scriptContent.lastIndexOf('}');
        if (lastBraceIndex !== -1) {
          scriptContent = scriptContent.substring(0, lastBraceIndex) + 
                         '\n}\n' + 
                         scriptContent.substring(lastBraceIndex);
        }
      }
      
      // 检查运行时代码是否格式正确
      if (scriptContent.includes('// @runtime-only') && !scriptContent.includes('export default {')) {
        // 如果是运行时代码和组件定义分离的格式，进行修复
        scriptContent = scriptContent.replace(/\/\/\s*@runtime-only([\s\S]*?)\/\/\s*@runtime-end/g, (runtimeMatch, runtimeCode) => {
          return `\n// @runtime-only\nexport default {\n  name: '${componentName}',\n  props: {\n    datas: {\n      type: Object,\n      required: true\n    },\n    isPreviewMode: {\n      type: Boolean,\n      default: false\n    },\n    isExportMode: {\n      type: Boolean,\n      default: false\n    }\n  },\n  ${runtimeCode.trim()}\n}\n// @runtime-end`;
        });
      } else if (scriptContent.includes('// @runtime-only')) {
        // 确保运行时代码在组件定义内部
        scriptContent = scriptContent.replace(/\/\/\s*@runtime-only([\s\S]*?)\/\/\s*@runtime-end/g, (runtimeMatch, runtimeCode) => {
          return runtimeCode;
        });
      }
      
      return `<script>\n${scriptContent}\n</script>`;
    });

    return content;
  }
}
// 创建单例实例
const vueProjectExportService = new VueProjectExportService();

export default vueProjectExportService; 
